let instance = null;

class WaterMark {
    doc = window.top.document;
    type = "text";
    len = 0;
    html = "";
    timer = null;
    options = {
        // text / img
        text: "WATERMARK",
        fontStyle: "font-size:18px;color:#000;",
        src: "",
        width: 200,
        height: 150,
        rotate: -15,
        alpha: 0.15,
        interval: 2000,
        intervalCheck: true,
        clickCheck: true
    };

    constructor(options,doc) {
        this.setOptions(options,doc);
        this.update();
    }

    handleClick = () => {
        if (this.checkChange()) {
            this.update();
        }
    };

    des = () => {
        clearInterval(this.timer);
        window.top.onresize = undefined;
        this.doc.removeEventListener("click", this.handleClick);
        const wmWrap = this.doc.getElementById("wf_watremark_wrap");
        if (wmWrap) {
            this.doc.body.removeChild(wmWrap);
        }
    };

    checkChange = () => {
        const wrap = this.doc.getElementById("wf_watremark_wrap");
        return !wrap || wrap.innerHTML !== this.html;
    };

    setOptions = (options = {},doc) => {
        if(doc) this.doc = doc;
        this.options = {...this.options, ...options};
        const {intervalCheck, interval, clickCheck} = this.options;
        if (this.timer) {
            clearInterval(this.timer);
        }
        if (intervalCheck) {
            this.timer = setInterval(() => this.handleClick(), interval);
        }
        if (clickCheck) {
            this.doc.addEventListener("click", this.handleClick);
        } else {
            this.doc.removeEventListener("click", this.handleClick);
        }
        window.top.onresize = () => {
            this.update(options);
        };
    };

    // 判断重新生成dom条件
    isUpdate = marks => {
        const {alpha, rotate} = this.options;
        if (!marks || marks.length === 0) {
            // 初始化
            return true;
        } else if (marks.length != this.len) {
            // 修改宽高的值
            return true;
        } else if (marks[0].style.transform !== `rotate(${rotate}deg)`) {
            // 修改旋转角度
            return true;
        } else if (marks[0].style.opacity !== alpha) {
            // 修改透明度
            return true;
        }
        return false;
    };

    update = type => {
        const {src, alpha, rotate, text, fontStyle} = this.options;
        let {width, height} = this.options;
        width = width > 0 ? width : 200;
        height = height > 0 ? height : 150;
        let wrap = this.doc.getElementById("wf_watremark_wrap");
        if (!wrap) {
            wrap = this.doc.createElement("div");
            wrap.id = "wf_watremark_wrap";
            this.doc.body.appendChild(wrap);
        }

        let bg = this.doc.getElementById("wf_watremark");
        if (!bg) {
            bg = this.doc.createElement("div");
            bg.id = "wf_watremark";
            bg.style.display = "block";
            bg.style.pointerEvents = "none";
            bg.style.position = "fixed";
            bg.style.width = "100%";
            bg.style.height = "100%";
            bg.style.zIndex = 99999;
            bg.style.top = 0;
            bg.style.left = 0;
            bg.style.textAlign = "center";
            wrap.appendChild(bg);
        }

        // 检测图片是否有效
        if (src && type !== "text") {
            this.type = "img";
            let img = this.doc.getElementById("wf_watremark_img_test");
            if (!img) {
                img = this.doc.createElement("img");
                img.id = "wf_watremark_img_test";
                img.style.display = "none";
                img.onerror = () => {
                    this.type = "text";
                    this.update(this.type);
                };
                this.doc.body.appendChild(img);
            }
            img.src = src;
        } else {
            this.type = "text";
        }

        const w = this.doc.documentElement.clientWidth;
        const h = this.doc.documentElement.clientHeight;

        const x = Math.ceil(w / width);
        const y = Math.ceil(h / height);

        this.len = x * y + 2;

        let marks = this.doc.querySelectorAll(".wf-watremark-mark");
        if (this.isUpdate(marks)) {
            bg.innerHTML = "";
            for (let i = 0; i < this.len; i++) {
                let mark = this.doc.createElement("div");
                mark.className = "wf-watremark-mark";
                mark.style.width = `${width}px`;
                mark.style.height = `${height}px`;
                mark.style.pointerEvents = "none";
                mark.style.zIndex = -1;
                mark.style.float = "left";
                mark.style.overflow = "visible";
                mark.style.opacity = alpha;
                mark.style.transform = `rotate(${rotate}deg)`;
                mark.style["-ms-transform"] = `rotate(${rotate}deg)`;
                mark.style.position = "relative";
                bg.appendChild(mark);
            }
            marks = this.doc.querySelectorAll(".wf-watremark-mark");
        }

        Array.prototype.forEach.call(marks, (m, i) => {
            if (x !== 1 && (i + 1) % x === 0) {
                m.style.marginRight = `-${width}px`;
            } else {
                m.style.marginRight = "0";
            }
            if (this.type === "text") {
                m.innerHTML = `<div style="width:100%;position:absolute;top:50%;transform:translateY(-50%);"><p style="pointer-events:none;${fontStyle}">${text}</p></div>`;
            } else {
                m.innerHTML = `<img alt="" src="${src}" style="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);pointer-events:none;max-width:100%;max-height:100%;"></img>`;
            }
        });

        this.html = wrap.innerHTML;
    };
}

const WfWaterMark = function (options = {},doc) {
    if (instance) {
        instance.setOptions(options,doc);
        instance.update();
    } else {
        instance = new WaterMark(options,doc);
    }
};

// 清除水印
WfWaterMark.destory = () => {
    if (instance) {
        instance.des();
        instance = null;
    }
};

// 格式化文档水印文本内容
function formatContent(options) {
    let text = options.text || "";
    const fontStyle = `font-family:${options.familyname ||
    "微软雅黑"};font-size:${options.fontsize || 14}px;color:${options.color ||
    "#000"};`;
    let lines = "";
    // 处理多行文本的换行
    text
        .split("\n")
        .forEach(line => (lines += `<p style="${fontStyle}">` + line + "</p>"));
    text = lines;
    return text;
}

// 处理水印设置内容
const handleWMSetting = (wmSetting = {}, params = {}) => {
    const rotate = -Number(wmSetting.rotate);
    const alpha = Number(wmSetting.opacity) / 100;
    var options = {
        src:
            wmSetting.watermarktype == "2"
                ? "/weaver/weaver.file.FileDownload?fileid=" + wmSetting.imageid
                : "",
        text:
            wmSetting.watermarktype == "1"
                ? params && params.document
                ? formatContent(wmSetting)
                : wmSetting.wmcontent
                : "",
        width: wmSetting.wmwidth > 0 ? wmSetting.wmwidth : 200,
        height: wmSetting.wmheight > 0 ? wmSetting.wmheight : 150,
        rotate,
        alpha
    };
    return options;
};

// 处理水印黑白名单规则
const handleSettingByHash = wmSetting => {
    const pathname = window.location.pathname || "";
    const hash = window.location.hash || "";
    let index = hash.indexOf("?");
    index = index !== -1 ? index : hash.length - 1;
    const href = pathname + hash.substring(0, index);
    if (wmSetting) {
        const {isopen, whitelist, blacklist} = wmSetting;
        const list = isopen === 1 || isopen === "1" ? blacklist : whitelist;
        const match = (list || []).findIndex(value => new RegExp(value).test(href));
        if (match !== -1) {
            isopen === 1 || isopen === "1"
                ? WfWaterMark.destory()
                : WfWaterMark(handleWMSetting(wmSetting));
        } else {
            isopen === 1 || isopen === "1"
                ? WfWaterMark(handleWMSetting(wmSetting))
                : WfWaterMark.destory();
        }
    }
};

// 处理hash变化
const handleHashChange = () => {
    handleSettingByHash(WfWaterMark.wmSetting);
};

// 监听哈希变化
if ("onhashchange" in window) {
    if (window.addEventListener) {
        window.removeEventListener("hashchange", handleHashChange);
        window.addEventListener("hashchange", handleHashChange);
    } else if (window.attachEvent) {
        window.detachEvent("onhashchange", handleHashChange);
        window.attachEvent("onhashchange", handleHashChange);
    } else {
        window.onhashchange = handleHashChange;
    }
}

WfWaterMark.handleHashChange = handleHashChange;
WfWaterMark.handleWMSetting = handleWMSetting;
WfWaterMark.handleSettingByHash = handleSettingByHash;
WfWaterMark.formatContent = formatContent;

export default WfWaterMark;